/*
 * BasicRFIDSample.java
 *
 * COPYRIGHT (c) 2005 INTERMEC TECHNOLOGIES CORPORATION, ALL RIGHTS RESERVED
 */
 
import java.awt.*;
import com.intermec.datacollection.rfid.*;

/**
 * This sample demonstrates the Basic RFID API methods. It creates an instance
 * of BasicBRIReader to open a reader connection, and provides an user interface
 * to send a BRI command to the reader and view the resopnse message in the text
 * area.
 */
public class BasicRFIDSample extends Frame
{
	private BasicBRIReader m_Reader = null;
	private String         m_sURI = null;
	private Panel          m_PanelNorth = new Panel(new GridBagLayout());
	private Label          m_LabelCommand = new Label("Command:");
	private TextField      m_TextFieldCommand = new TextField(20);
	private Button         m_BtnSend = new Button("Send");
	private TextArea       m_TextArea = new TextArea();
	private Panel          m_PanelSouth = new Panel(new FlowLayout(FlowLayout.CENTER, 20, 5));
	private Button         m_BtnClear = new Button("Clear");
	private Button         m_BtnClose = new Button("Close");

	BasicRFIDSample (String aTitle, String aURIString)
	{
		super(aTitle);
		m_sURI = aURIString;

		initComponents();

		m_Reader = new BasicBRIReader();

		m_Reader.addReaderEventListener(new BasicReaderEventListener() {
			public void receivedReaderEvent(BasicReaderEvent aEvent) {
				final BasicReaderEvent event = aEvent;
				int iEventType = aEvent.getEventType();
				switch (iEventType)
				{
					case BasicReaderEvent.EVT_BATTERY:
						/**
						 * Uses EventQueue.invokeLater to ensure the UI update
						 * executes on the AWT event dispatching thread. 
						 */
						EventQueue.invokeLater(new Runnable() {
							public void run()
							{
								m_TextArea.append("A battery event occurred:\n");
								m_TextArea.append("  Event data: " + event.getEventDataString() );
								m_TextArea.append("\n");
							}
						});
						break;

					case BasicReaderEvent.EVT_DCE:
						/**
						 * Uses EventQueue.invokeLater to ensure the UI update
						 * executes on the AWT event dispatching thread. 
						 */
						EventQueue.invokeLater(new Runnable() {
							public void run()
							{
								int    iDCEEventType = event.getDCEEventType();
	
								if (BasicReaderEvent.DCEEventTypes.DCE_EVT_UNKNOWN == iDCEEventType)
								{
									m_TextArea.append("An unknown DCE event occurred:\n");
								}
								else if (BasicReaderEvent.DCEEventTypes.DCE_EVT_SHUTDOWN == iDCEEventType)
								{
									m_TextArea.append("A DCE SHUTDOWN event occurred:\n");
								}
								else if (BasicReaderEvent.DCEEventTypes.DCE_EVT_BUTTON == iDCEEventType)
								{
									m_TextArea.append("A DCE BUTTON event occurred:\n");
								}
								else if (BasicReaderEvent.DCEEventTypes.DCE_EVT_DEVICE == iDCEEventType)
								{
									m_TextArea.append("A DCE DEVICE event occurred:\n");
								}
	
								m_TextArea.append("  Data: " + event.getDCEDataString());
								m_TextArea.append("\n");
							}
						});
						break;

					case BasicReaderEvent.EVT_RADIO:
						/**
						 * Uses EventQueue.invokeLater to ensure the UI update
						 * executes on the AWT event dispatching thread. 
						 */
						EventQueue.invokeLater(new Runnable() {
							public void run()
							{
								m_TextArea.append("A radio event occurred:\n");
								m_TextArea.append("  RadioDutyCyleTimeLeft: " + event.getRadioDutyCycleTimeleft());
								m_TextArea.append("\n");
							}
						});
						break;
						
					case BasicReaderEvent.EVT_READER_RECONNECTED:
						/**
						 * Uses EventQueue.invokeLater to ensure the UI update
						 * executes on the AWT event dispatching thread. 
						 */
						EventQueue.invokeLater(new Runnable() {
							public void run()
							{
								m_TextArea.append("A reader reconnected event occurred:\n");
								m_TextArea.append("  Event data: " + event.getEventDataString() );
								m_TextArea.append("\n");
							}
						});
						break;
						
					case BasicReaderEvent.EVT_RESET:
						/**
						 * Uses EventQueue.invokeLater to ensure the UI update
						 * executes on the AWT event dispatching thread. 
						 */
						EventQueue.invokeLater(new Runnable() {
							public void run()
							{
								m_TextArea.append("A reader reset event occurred:\n");
								m_TextArea.append("  Event data: " + event.getEventDataString() );
								m_TextArea.append("\n");
							}
						});
						break;

					case BasicReaderEvent.EVT_TAG:
						/**
						 * Uses EventQueue.invokeLater to ensure the UI update
						 * executes on the AWT event dispatching thread. 
						 */
						EventQueue.invokeLater(new Runnable() {
							public void run()
							{
								m_TextArea.append("A tag event occurred:\n");
								m_TextArea.append("  Data: " + event.getTagDataString());
								m_TextArea.append("\n");
							}
						});
						break;

					case BasicReaderEvent.EVT_THERMAL:
						/**
						 * Uses EventQueue.invokeLater to ensure the UI update
						 * executes on the AWT event dispatching thread. 
						 */
						EventQueue.invokeLater(new Runnable() {
							public void run()
							{
								m_TextArea.append("A thermal event occurred:\n");
								m_TextArea.append("  Event data: " + event.getEventDataString() );
								m_TextArea.append("\n");
							}
						});
						break;
						
					case BasicReaderEvent.EVT_TRIGGER:
						/**
						 * Uses EventQueue.invokeLater to ensure the UI update
						 * executes on the AWT event dispatching thread. 
						 */
						EventQueue.invokeLater(new Runnable() {
							public void run()
							{
								m_TextArea.append("A trigger event occurred:\n");
								m_TextArea.append("  Trigger Name: " + event.getTriggerNameString() );
								m_TextArea.append(", Name Len: " + event.getTriggerNameLen());
								m_TextArea.append(", GPIO: " + event.getGpioState());
								m_TextArea.append("\n");
							}
						});
						break;

					case BasicReaderEvent.EVT_TRIGGERACTION:
						/**
						 * Uses EventQueue.invokeLater to ensure the UI update
						 * executes on the AWT event dispatching thread. 
						 */
						EventQueue.invokeLater(new Runnable() {
							public void run()
							{
								m_TextArea.append("A trigger action event occurred:\n");
								m_TextArea.append("  Event data: " + event.getEventDataString() );
								m_TextArea.append("\n");
							}
						});
						break;
				} //endswitch
			} //endof receivedReaderEvent
		});

		try
		{
			m_Reader.open(m_sURI);
		}
		catch (BasicReaderException brExcept)
		{
			displayBasicReaderException(brExcept);
		}		
	}

	private void initComponents()
	{
		setLayout(new BorderLayout());
		add(m_PanelNorth, BorderLayout.NORTH);

		java.awt.GridBagConstraints constraintsLabelCommand = new java.awt.GridBagConstraints();
		constraintsLabelCommand.gridx = 0; constraintsLabelCommand.gridy = 0;
		constraintsLabelCommand.anchor = java.awt.GridBagConstraints.WEST;
		constraintsLabelCommand.insets = new java.awt.Insets(5, 5, 3, 0);
		m_PanelNorth.add(m_LabelCommand, constraintsLabelCommand);
				
		java.awt.GridBagConstraints constraintsTxtCommand = new java.awt.GridBagConstraints();
		constraintsTxtCommand.gridx = 1; constraintsTxtCommand.gridy = 0;
		constraintsTxtCommand.anchor = java.awt.GridBagConstraints.WEST;
		constraintsTxtCommand.fill = java.awt.GridBagConstraints.HORIZONTAL;
		constraintsTxtCommand.insets = new java.awt.Insets(5, 5, 3, 5);
		constraintsTxtCommand.weightx = 1.0;
		m_PanelNorth.add(m_TextFieldCommand, constraintsTxtCommand);
		
		java.awt.GridBagConstraints constraintsBtnSend = new java.awt.GridBagConstraints();
		constraintsBtnSend.gridx = 2; constraintsBtnSend.gridy = 0;
		constraintsBtnSend.anchor = java.awt.GridBagConstraints.WEST;
		constraintsBtnSend.insets = new java.awt.Insets(5, 5, 3, 5);
		m_PanelNorth.add(m_BtnSend, constraintsBtnSend);
		
		add(m_TextArea, BorderLayout.CENTER);
		
		// Register action listener for the Send button
		m_BtnSend.addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(java.awt.event.ActionEvent e)
			{
				sendBRICommand();
			}
		});
		m_TextFieldCommand.addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(java.awt.event.ActionEvent e)
			{
				sendBRICommand();
			}
		});

		add(m_PanelSouth, BorderLayout.SOUTH);
		m_PanelSouth.add(m_BtnClear);
		m_PanelSouth.add(m_BtnClose);

		// Register action listener for the Clear button
		m_BtnClear.addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(java.awt.event.ActionEvent e)
			{
				m_TextFieldCommand.setText("");
				m_TextArea.setText("");
			}
		});

		// Register action listener for the Close button
		m_BtnClose.addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(java.awt.event.ActionEvent e)
			{
				exitApp();
			}
		});
	}

	public void exitApp()
	{
		try
		{
			if (m_Reader != null)
			{
				m_Reader.close();
			}
		}
		catch (BasicReaderException brExcept)
		{
			displayBasicReaderException(brExcept);
		}
        dispose(); // dispose the frame
		System.exit(0);
	}
	
	private void sendBRICommand()
	{
		String sResponse;
				
		try
		{
			m_TextArea.append(m_TextFieldCommand.getText());
			m_TextArea.append("\n");

			sResponse = m_Reader.execute(m_TextFieldCommand.getText());

			m_TextArea.append(sResponse);
			m_TextArea.append("\n");
		}
		catch (BasicReaderException brExcept)
		{
			displayBasicReaderException(brExcept);
		}
	}

	private void displayBasicReaderException(BasicReaderException brExcept)
	{
		m_TextArea.append("BasicReaderException: ");
		m_TextArea.append(brExcept.getMessage());
		m_TextArea.append("\n");
	}

	public static void displayUsage()
	{
		System.out.println("Usage: java [VMOptions] BasicRFIDSample aURIString");
		System.out.println("Where:");
		System.out.println("  VMOptions - specify classpath, system property definitions, etc.");
		System.out.println("  aURIString - specify an URI string to identify the reader address.");
		System.out.println("               Sample URI strings:");
		System.out.println("                 tcp://172.20.32.101:2189");
		System.out.println("                 serial://COM1");
	}

	public static void main(String[] args)
	{
		if (0 == args.length)
		{
			displayUsage();
			return;
		}

		final BasicRFIDSample brTest = new BasicRFIDSample("BasicRFIDSample", args[0]);

		brTest.addWindowListener(new java.awt.event.WindowAdapter()
		{
			public void windowClosing(java.awt.event.WindowEvent e)
			{
				brTest.exitApp();
			};
		});

		brTest.setSize(400, 400);
		brTest.setVisible(true);
	} //endof main
}
